﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Collections;
using System.IO;
using System.Xml.Serialization;

namespace Infrastructure.Configuration
{
    /// <summary>
    /// 配置管理器
    /// 实现对配置文件的管理
    /// </summary>
    public class ConfigFileManagement
    {

        #region ConfigFilepath

        /// <summary>
        /// 配置管理器的静态属性,配置文件路径
        /// </summary>
        /// <value></value>
        public static string ConfigFilepath
        {
            get
            {
                string path;
                try
                {
                    path = System.Configuration.ConfigurationManager.AppSettings["ConfigFilepath"];
                }
                catch
                {
                    throw new Exception("The Configure File is not exists.");
                }
                if (path == null || !System.IO.Directory.Exists(path)) path = AppDomain.CurrentDomain.BaseDirectory;
                return path;
            }
        }
        #endregion

        #region GetFullname

        /// <summary>
        /// 配置管理器的静态方法，读取配置文件全名（包含路径）。
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <returns>文件全名（包含路径）</returns>
        public static string GetFullname(string filename)
        {
            string filefullname = filename;
            if (!System.IO.File.Exists(filename))
            {
                string[] s = filename.Split('\\');
                filefullname = s.Length > 0 ? s[s.Length - 1] : filename;
                filefullname = string.Format("{0}{1}", ConfigFilepath, filefullname);
            }
            return filefullname;
        }
        #endregion

        #region SetFile2Normal


        /// <summary>
        /// 配置管理器的静态方法
        /// 将文件设置为正常属性
        /// 取消所有特殊属性，比如只读，隐藏。。。
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <returns>设置成功返回true,否则false。</returns>
        public static bool SetFile2Normal(string filename)
        {
            if (System.IO.File.Exists(filename))
            {
                new FileInfo(filename) { Attributes = System.IO.FileAttributes.Normal };
                return true;
            }
            return false;
        }
        #endregion

        #region Save

        /// <summary>
        /// 配置管理器的静态方法，将配置实例保存成配置文件
        /// </summary>
        /// <param name="setting">配置实例</param>
        public static void Save(object setting)
        {
            string filename = setting.GetType().Name + ".xml";
            Save(setting, filename);
        }

        /// <summary>
        /// 配置管理器的静态方法，将配置实例保存到对应的配置文件
        /// </summary>
        /// <param name="setting">配置实例</param>
        /// <param name="filename">文件名</param>
        public static void Save(object setting, string filename)
        {

            TextWriter writer = null;
            string filefullname = GetFullname(filename);
            try
            {
                SetFile2Normal(filefullname);
                var s = new XmlSerializer(setting.GetType());
                writer = new StreamWriter(filefullname, false);
                s.Serialize(writer, setting);

            }
            catch (Exception ex)
            {
                System.Console.Write(ex.StackTrace);

            }
            finally
            {
                if (writer != null) writer.Close();
            }
        }
        #endregion

        #region Load

        public static object Load(Type type)
        {
            return Load(type, false);
        }

        /// <summary>
        /// 配置管理器的静态方法
        /// 根据传入配置类名读取对应配置文件，返回配置实例
        /// </summary>
        /// <param name="type">配置类名</param>
        /// <param name="autoCreateFile">是否自动创建配置文件</param>
        /// <returns>配置实例</returns>
        public static object Load(Type type, bool autoCreateFile)
        {
            string filename = type.Name + ".xml";
            return Load(type, filename, autoCreateFile);
        }

        /// <summary>
        /// 配置管理器的静态方法
        /// 根据传入配置类名以及配置文件读取配置，返回配置实例
        /// </summary>
        /// <param name="type">配置类名</param>
        /// <param name="filename">文件名</param>
        /// <param name="autoCreateFile">是否自动创建配置文件</param>
        /// <returns>配置实例</returns>
        public static object Load(Type type, string filename, bool autoCreateFile)
        {
            System.IO.FileStream stream = null;
            if (filename.Length == 0)
                filename = type.Name + ".xml";
            // System.Xml.XmlReader reader = null;
            object obj;
            try
            {
                string filefullname = GetFullname(filename);

                if (!System.IO.File.Exists(filefullname))
                {
                    if (autoCreateFile)
                    {
                        Save(System.Activator.CreateInstance(type));
                    }
                    else
                        throw new Exception(string.Format("The file:{0} is not exists.", filefullname));
                }
                stream = new FileStream(filefullname, FileMode.Open);
                var serializer = new XmlSerializer(type);

                obj = serializer.Deserialize(stream);
            }
            finally
            {
                if (stream != null) stream.Close();
            }
            return obj;

        }

        #endregion

        #region LoadList

        /// <summary>
        /// 配置管理器的静态方法
        /// 根据传入配置类型以及配置文件，读取相应的配置实例列表
        /// </summary>
        /// <param name="itemtype">配置类型</param>
        /// <param name="filename">文件名</param>
        /// <returns>配置实例列表</returns>
        public static ArrayList LoadList(Type itemtype, string filename)
        {
            System.Xml.XmlReader reader = null;
            var list = new ArrayList();
            try
            {
                string filefullname = GetFullname(filename);
                if (!System.IO.File.Exists(filefullname)) throw new Exception(string.Format("The file:{0} is not exists.", filefullname));
                reader = new XmlTextReader(new StreamReader(filename));
                var serializer = new XmlSerializer(itemtype);
                while (!reader.EOF)
                {

                    if (reader.IsStartElement(itemtype.Name) && reader.NodeType == System.Xml.XmlNodeType.Element)
                    {
                        list.Add(serializer.Deserialize(reader));
                    }
                    else
                    {
                        reader.Read();
                    }
                }
            }
            finally
            {
                if (reader != null) reader.Close();
            }
            return list;
        }
        #endregion
    }
}
